﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using jp110311.StorageModels;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;

namespace MvcWebRole1.Tests.Services
{
    /// <summary>
    /// UserMessagingServiceTest の概要の説明
    /// </summary>
    [TestClass]
    public class UserMessagingServiceTest
    {
        /// <summary>
        ///現在のテストの実行についての情報および機能を
        ///提供するテスト コンテキストを取得または設定します。
        ///</summary>
        public TestContext TestContext { get; set; }

        #region 追加のテスト属性
        //
        // テストを作成する際には、次の追加属性を使用できます:
        //
        // クラス内で最初のテストを実行する前に、ClassInitialize を使用してコードを実行してください
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // クラス内のテストをすべて実行したら、ClassCleanup を使用してコードを実行してください
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // 各テストを実行する前に、TestInitialize を使用してコードを実行してください
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // 各テストを実行した後に、TestCleanup を使用してコードを実行してください
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestInitialize()]
        public void MyTestInitialize()
        {
            CloudStorageAccount account = CloudStorageAccount.DevelopmentStorageAccount;
            CloudTableClient client = account.CreateCloudTableClient();
            var tables = client.ListTables().ToList();
            foreach (var table in tables)
            {
                client.DeleteTableIfExist(table);
                client.CreateTableIfNotExist(table);
            }            
        }

        [TestMethod]
        public void SendAndListMarkChanges()
        {
            UserMessagingService.UseDevelopmentStorage = true;
            var mockCacheService = new MockCacheService();
            UserMessagingService.CacheService = mockCacheService;

            DateTime sendAt = DateTime.UtcNow;
            UserMessagingService.SendMessage("1234567@test", sendAt, "1234567@test1;1234567@test2", "test", "testですよ");

            var msgs = UserMessagingService.ListUnreadMessage("1234567@test1", 0, 20).ToList();
            mockCacheService.Clear();

            Assert.AreEqual(1, msgs.Count);
            // Assert.AreEqual(0, sendAt.CompareTo(msgs[0].SendAt) );
            Assert.AreEqual("test",msgs[0].Title);
            Assert.AreEqual("1234567@test",msgs[0].Sender);
            Assert.AreEqual("testですよ",msgs[0].Content);

            UserMessagingService.MarkMessageImportance("1234567@test1", msgs[0].RowKey);
            UserMessagingService.MarkMessageToRead("1234567@test1", msgs[0].RowKey);

            mockCacheService.Clear();

            msgs = UserMessagingService.ListUnreadMessage("1234567@test1", 0, 20).ToList();
            Assert.AreEqual(0, msgs.Count);

            msgs = UserMessagingService.ListImportanceMessage("1234567@test1", 0, 20).ToList();
            Assert.AreEqual(1, msgs.Count);

            UserMessagingService.UnmarkMessageImportance("1234567@test1", msgs[0].RowKey);
            mockCacheService.Clear();

            msgs = UserMessagingService.ListImportanceMessage("1234567@test1", 0, 20).ToList();
            Assert.AreEqual(0, msgs.Count);

        }


        [TestMethod]
        public void AddressBookAddAndQueries()
        {
            UserMessagingService.UseDevelopmentStorage = true;
            var mockCacheService = new MockCacheService();
            UserMessagingService.CacheService = mockCacheService;

            UserMessagingService.AddressBookAdd("1234567@test", new[] { "1234567@test1" }, "test1", new[] { "test1" });

            mockCacheService.Clear();

            var listAddr = UserMessagingService.GetAddressBookItems("1234567@test", 0, 20);
            Assert.AreEqual( 1,listAddr.Count() );
            Assert.AreEqual("1234567@test1", listAddr.ElementAt(0).BookedUser);
            Assert.AreEqual("test1", listAddr.ElementAt(0).Memo );
            Assert.AreEqual("test1", listAddr.ElementAt(0).TagList );
            listAddr = UserMessagingService.GetAddressBookItemsByTag("1234567@test", "test1", 0, 20);
            Assert.AreEqual(1, listAddr.Count());
            listAddr = UserMessagingService.GetAddressBookItemsByTag("1234567@test", "test2", 0, 20);
            Assert.AreEqual(0, listAddr.Count());

            UserMessagingService.AddressBookAdd("1234567@test", new[]{"1234567@test2"},"test2",new[]{"test2"});
            UserMessagingService.AddressBookAdd("1234567@test", new[]{"1234567@test1"},"test", new[]{"addTag"});

            mockCacheService.Clear();

            listAddr = UserMessagingService.GetAddressBookItems("1234567@test", 0, 20);
            Assert.AreEqual(2, listAddr.Count());
            listAddr = UserMessagingService.GetAddressBookItemsByTag("1234567@test", "test1", 0, 20);
            Assert.AreEqual(1, listAddr.Count());
            listAddr = UserMessagingService.GetAddressBookItemsByTag("1234567@test", "addTag", 0, 20);
            Assert.AreEqual(1, listAddr.Count());
        }
    }

    public class MockCacheService : ICacheService
    {
        readonly Dictionary<string,object > _cacheContent = new Dictionary<string, object>();

        public object Get(string key)
        {
            object value;
            if (_cacheContent.TryGetValue(key, out value)) return value;
            return null;
        }

        public void Insert(string key, object value)
        {
            _cacheContent.Add(key,value);
        }

        internal void Clear()
        {
            _cacheContent.Clear();
        }
    }
}
